<?php
/**
 * Slipstream :: Highly adaptive dependency injection framework
 * Copyright 2010-2011 Ian Unruh (Xerof3ar)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
namespace Slipstream\Configuration;
use ArrayObject;

/**
 * A policy is a single unit of configuration
 *
 * <b>Characteristics of a policy:</b>
 * <ul>
 *   <li>Contains any number of validated options</li>
 *   <li>Able to compare itself to another policy to determine equality</li>
 *   <li>Has certain identifiers that make them able to be matched to other policies</li>
 *   <li>Able to merge itself with any number of other policies to
 *       create a single policy for consumption by build contributors</li>
 *   <li>Should be as simple as possible to avoid side-effects</li>
 * </ul>
 *
 * @author Ian Unruh (Xerof3ar) <ianunruh@gmail.com>
 * @since Class avaliable since release 1.0
 */
interface PolicyInterface
{
	/**
	 * Returns the value of a named option
	 *
	 * @throws InvalidArgumentException If option is undefined
	 * @param string $name
	 * @return mixed
	 */
	public function get($name);
	
	/**
	 * Sets the value of a named option
	 *
	 * @throws InvalidArgumentException If option is undefined
	 * @throws InvalidArgumentException If value of option is invalid
	 * @param string $name
	 * @param mixed $value
	 * @return void
	 */
	public function set($name, $value);
	
	/**
	 * Sets the values of multiple options using a map
	 *
	 * @param Traversable<string,mixed> $options
	 * @return void
	 */
	public function setAll($options);
	
	/**
	 * Returns true if this policy matches another policy
	 *
	 * @param PolicyInterface $policy
	 * @return bool
	 */
	public function matches(PolicyInterface $policy);
	
	/**
	 * Merges a set of policies with this policy to create a single policy
	 *
	 * @param ArrayObject<PolicyInterface> $policies
	 * @return PolicyInterface
	 */
	public function merge(ArrayObject $policies);
}